﻿package mortal.game.manager.window3d
{
    import __AS3__.vec.*;
    import baseEngine.basic.*;
    import baseEngine.system.*;
    import com.gengine.debug.*;
    import com.gengine.global.*;
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
    import flash.utils.*;
    import frEngine.core.*;
    import frEngine.primitives.*;
    import frEngine.primitives.object2d.*;
    import mortal.component.window.*;
    import mortal.game.manager.*;
    import mortal.game.scene3D.*;

    public class Rect3DManager extends Object
    {
        private var _mask1:Shape;
        private var _mask2:Shape;
        private var _findRect3dObjectByWindow:Dictionary;
        private var _rect3dList:Array;
        private var _pool:Vector.<Rect3DObject>;
        private var _curLen:int = 0;
        private var _scene3d:Scene3D;
        private var _updateMask:Boolean = true;
        private var drawingCommand:Vector.<int>;
        private var _blackMask3d:FrQuad;
        private var _blackMask3dIsHide:Boolean = true;
        public static const instance:Rect3DManager = new Rect3DManager;

        public function Rect3DManager()
        {
            this._mask1 = new Shape();
            this._mask2 = new Shape();
            this._findRect3dObjectByWindow = new Dictionary(false);
            this._rect3dList = new Array();
            this._pool = new Vector.<Rect3DObject>;
            this.drawingCommand = new Vector.<int>;
            this.drawingCommand.push(GraphicsPathCommand.MOVE_TO, GraphicsPathCommand.LINE_TO, GraphicsPathCommand.LINE_TO, GraphicsPathCommand.LINE_TO, GraphicsPathCommand.LINE_TO);
            var _loc_1:* = new Img2D("", Global3D.nullBitmapData, new Rectangle(0, 0, 1, 1), true, false);
            _loc_1.render.draw(_loc_1, _loc_1.material);
            return;
        }// end function

        public function init(param1:GameScene3D) : void
        {
            this._scene3d = param1;
            if (!this._mask1.parent)
            {
                Global.stage.addChild(this._mask1);
            }
            if (!this._mask2.parent)
            {
                Global.stage.addChild(this._mask2);
            }
            this._blackMask3d = new FrQuad("blackMask3d", 0, 0, 100, 100, true);
            this._blackMask3d.setMaterial(1711276032, 0, "blackMask3d");
            this._blackMask3d.material.materialParams.depthWrite = false;
            this._blackMask3d.setMateiralBlendMode(EBlendType.BLEND_ALPHA0);
            return;
        }// end function

        public function showBlackMask3d() : void
        {
            this._blackMask3dIsHide = false;
            return;
        }// end function

        public function hideBlackMask3d() : void
        {
            this._blackMask3dIsHide = true;
            return;
        }// end function

        public function resize() : void
        {
            var _loc_2:* = undefined;
            var _loc_3:Rect3DObject = null;
            this._blackMask3d.setTo(0, 0, 100, 100, true);
            this._blackMask3d.sceneRect = Global3D.scene.viewPort;
            var _loc_1:Boolean = false;
            for (_loc_2 in this._findRect3dObjectByWindow)
            {
                
                _loc_3 = this._findRect3dObjectByWindow[_loc_2];
                if (!_loc_3.hasClose && !_loc_3.isHide)
                {
                    _loc_3.calculateRect();
                    _loc_3.moveAll3d();
                }
                _loc_1 = true;
            }
            if (this._updateMask || _loc_1)
            {
                this.clearOldMask(null);
            }
            return;
        }// end function

        public function getInRenderTexture(param1:Array, param2:Array) : void
        {
            var _loc_4:Rect3DObject = null;
            var _loc_3:* = this._rect3dList.length;
            var _loc_5:int = 0;
            while (_loc_5 < _loc_3)
            {
                
                _loc_4 = this._rect3dList[_loc_5];
                _loc_4.getInRenderTexture(param1, param2);
                _loc_5++;
            }
            return;
        }// end function

        public function renderRect3d() : void
        {
            var _loc_3:Rect3DObject = null;
            var _loc_1:* = this._rect3dList.length;
            if (this._updateMask && _loc_1 > 0)
            {
                this.redrawMask();
                this._updateMask = false;
            }
            if (this._blackMask3dIsHide == false)
            {
                this._blackMask3d.update();
                this._blackMask3d.draw(false);
            }
            var _loc_2:* = Global3D.scene;
            var _loc_4:int = 0;
            while (_loc_4 < _loc_1)
            {
                
                _loc_3 = this._rect3dList[_loc_4];
                if (_loc_3.useMask || _loc_3.allTimeIsTop)
                {
                }
                else if (!_loc_3.hasClose && !_loc_3.isHide)
                {
                    _loc_3.render(_loc_2);
                }
                _loc_4++;
            }
            _loc_4 = 0;
            while (_loc_4 < _loc_1)
            {
                
                _loc_3 = this._rect3dList[_loc_4];
                if (_loc_3.useMask || _loc_3.allTimeIsTop)
                {
                    if (!_loc_3.hasClose && !_loc_3.isHide)
                    {
                        _loc_3.render(_loc_2);
                    }
                }
                _loc_4++;
            }
            return;
        }// end function

        public function hasRegisterWindow(param1:IWindow3D) : Boolean
        {
            if (this.getRect3dByWindow(param1) != null)
            {
                return true;
            }
            return false;
        }// end function

        public function getRect3dByWindow(param1:IWindow3D) : Rect3DObject
        {
            if (!param1)
            {
                throw new Error("window 不能为空！");
            }
            return this._findRect3dObjectByWindow[param1];
        }// end function

        public function changeRect3dArea(param1:IWindow3D, param2:Rectangle) : void
        {
            var _loc_3:* = this.getRect3dByWindow(param1);
            _loc_3.reInit(param2, param1, _loc_3.useMask);
            this.windowMovingHander(null, param1);
            return;
        }// end function

        public function registerWindow(param1:Boolean, param2:Rectangle, param3:IWindow3D, param4:Boolean = false) : Rect3DObject
        {
            var _loc_5:* = this.getRect3dByWindow(param3);
            if (_loc_5 != null)
            {
                _loc_5.reInit(param2, param3, param1);
            }
            else
            {
                if (this._pool.length > 0)
                {
                    _loc_5 = this._pool.shift();
                    _loc_5.reInit(param2, param3, param1);
                }
                else
                {
                    _loc_5 = new Rect3DObject(param2, param3, param1);
                }
                this._rect3dList.push(_loc_5);
                this._findRect3dObjectByWindow[param3] = _loc_5;
            }
            _loc_5.allTimeIsTop = param4;
            _loc_5.calculateRect();
            _loc_5.moveAll3d();
            this.clearOldMask(_loc_5);
            param3.addEventListener(WindowEvent.SHOW, this.windowShowHander);
            param3.addEventListener(WindowEvent.CLOSE, this.closeHander);
            param3.addEventListener(WindowEvent.CLOSE_END, this.closeEndHander);
            param3.addEventListener(WindowEvent.POSITIONCHANGE, this.windowMovingHander);
            return _loc_5;
        }// end function

        private function closeHander(event:Event, param2:IWindow3D = null) : void
        {
            Log.system("取消显示Rect3D");
            if (event != null)
            {
                param2 = event.currentTarget as IWindow3D;
            }
            var _loc_3:* = this._findRect3dObjectByWindow[param2];
            if (!_loc_3)
            {
                return;
            }
            _loc_3.isHide = true;
            this.clearOldMask(_loc_3, true);
            return;
        }// end function

        public function closeEndHander(event:Event, param2:IWindow3D = null) : void
        {
            if (event != null)
            {
                param2 = event.currentTarget as IWindow3D;
            }
            var _loc_3:* = this._findRect3dObjectByWindow[param2];
            if (!_loc_3)
            {
                return;
            }
            if (_loc_3.hasClose == false)
            {
                _loc_3.hasClose = true;
                this.clearOldMask(_loc_3, true);
                var _loc_5:String = this;
                var _loc_6:* = this._curLen - 1;
                _loc_5._curLen = _loc_6;
                if (this._curLen == 0)
                {
                    LayerManager.setWindowSpriteMask(null, null);
                    LayerManager.windowLayer3D.removeEventListener(WindowEvent.WINDOWLEVELCHANGE, this.windowLayerChangeHander);
                }
            }
            this._pool.push(_loc_3);
            _loc_3.disposeImp();
            delete this._findRect3dObjectByWindow[param2];
            var _loc_4:* = this._rect3dList.indexOf(_loc_3);
            this._rect3dList.splice(_loc_4, 1);
            param2.removeEventListener(WindowEvent.CLOSE, this.closeHander);
            param2.removeEventListener(WindowEvent.CLOSE_END, this.closeEndHander);
            param2.removeEventListener(WindowEvent.SHOW, this.windowShowHander);
            param2.removeEventListener(WindowEvent.POSITIONCHANGE, this.windowMovingHander);
            return;
        }// end function

        public function disposeRect3d(param1:Rect3DObject) : void
        {
            param1.clear();
            this.clearOldMask(param1, true);
            if (param1.window)
            {
                param1.window.removeEventListener(WindowEvent.POSITIONCHANGE, this.windowMovingHander);
            }
            return;
        }// end function

        public function windowShowHander(event:Event, param2:IWindow3D = null) : void
        {
            Log.system("打开显示Rect3D");
            if (event != null)
            {
                param2 = event.currentTarget as IWindow3D;
            }
            var _loc_3:* = this.getRect3dByWindow(param2);
            if (!_loc_3)
            {
                return;
            }
            if (_loc_3.isHide)
            {
                _loc_3.isHide = false;
                this.clearOldMask(_loc_3, true);
            }
            _loc_3.calculateRect();
            if (this._rect3dList.indexOf(_loc_3) == -1)
            {
                this._rect3dList.push(_loc_3);
                this._rect3dList.sortOn("layer", Array.NUMERIC);
                this.clearOldMask(null, true);
            }
            if (_loc_3.hasClose)
            {
                var _loc_4:String = this;
                var _loc_5:* = this._curLen + 1;
                _loc_4._curLen = _loc_5;
                _loc_3.hasClose = false;
                _loc_3.moveAll3d();
                if (this._curLen == 1)
                {
                    LayerManager.windowLayer3D.addEventListener(WindowEvent.WINDOWLEVELCHANGE, this.windowLayerChangeHander);
                }
            }
            return;
        }// end function

        private function clearOldMask(param1:Rect3DObject, param2:Boolean = false) : void
        {
            this._updateMask = true;
            if (param1 && param1.useMask && param2)
            {
                if (param1.allTimeIsTop)
                {
                    Global.application.mask = null;
                }
                else
                {
                    var _loc_3:String = null;
                    param1.window.contentContainer.mask = null;
                }
            }
            return;
        }// end function

        private function windowLayerChangeHander(event:Event) : void
        {
            var _loc_5:Rect3DObject = null;
            var _loc_2:* = this._rect3dList.length;
            var _loc_3:String = "";
            var _loc_4:int = 0;
            while (_loc_4 < _loc_2)
            {
                
                _loc_5 = this._rect3dList[_loc_4];
                _loc_5.layer = this.getLayerId(DisplayObject(_loc_5.window));
                _loc_4++;
            }
            this._rect3dList.sortOn("layer", Array.NUMERIC);
            this.clearOldMask(null);
            return;
        }// end function

        private function getLayerId(param1:DisplayObject) : int
        {
            var _loc_2:int = 0;
            while (param1.parent)
            {
                
                _loc_2 = _loc_2 + param1.parent.getChildIndex(param1);
                param1 = param1.parent;
            }
            return _loc_2;
        }// end function

        private function windowMovingHander(event:Event, param2:IWindow3D = null) : void
        {
            if (event != null)
            {
                param2 = event.currentTarget as IWindow3D;
            }
            var _loc_3:* = this.getRect3dByWindow(param2);
            _loc_3.calculateRect();
            _loc_3.moveAll3d();
            this.clearOldMask(_loc_3);
            return;
        }// end function

        private function redrawMask() : void
        {
            var _loc_11:Rect3DObject = null;
            var _loc_12:Rect3DObject = null;
            var _loc_1:* = new Vector.<IGraphicsData>;
            var _loc_2:* = new Array();
            var _loc_3:* = Global.stage;
            var _loc_4:* = _loc_3.stageWidth;
            var _loc_5:* = _loc_3.stageHeight;
            var _loc_6:* = new Rectangle(0, 0, _loc_4, _loc_5);
            _loc_2.push(_loc_6);
            _loc_1.push(this.getPath(_loc_6));
            var _loc_7:* = this._rect3dList.length;
            var _loc_8:Boolean = true;
            var _loc_9:Boolean = false;
            var _loc_10:* = _loc_7 - 1;
            while (_loc_10 >= 0)
            {
                
                _loc_11 = this._rect3dList[_loc_10];
                if (!_loc_11.hasClose && _loc_11.useMask)
                {
                    if (!_loc_11.isHide)
                    {
                        this.spliteRect(_loc_11.rect, _loc_2, _loc_1);
                    }
                    this.drawGrphic(_loc_11.maskShape.graphics, _loc_1);
                    if (_loc_10 > 0)
                    {
                        _loc_12 = this.getNextUseMaskRect(_loc_10);
                        if (_loc_12)
                        {
                            this.drawGrphic(_loc_11.maskShape2.graphics, _loc_1);
                            var _loc_13:* = _loc_11.maskShape2;
                            _loc_12.window.contentTopOf3DSprite.mask = _loc_11.maskShape2;
                        }
                    }
                    if (_loc_8)
                    {
                        var _loc_13:String = null;
                        _loc_11.window.contentTopOf3DSprite.mask = null;
                        _loc_8 = false;
                    }
                    if (_loc_11.allTimeIsTop)
                    {
                        var _loc_13:* = _loc_11.maskShape;
                        Global.application.mask = _loc_11.maskShape;
                    }
                    else
                    {
                        var _loc_13:* = _loc_11.maskShape;
                        _loc_11.window.contentContainer.mask = _loc_11.maskShape;
                    }
                    _loc_9 = true;
                }
                _loc_10 = _loc_10 - 1;
            }
            if (_loc_9)
            {
                this.drawGrphic(this._mask1.graphics, _loc_1);
                this.drawGrphic(this._mask2.graphics, _loc_1);
                LayerManager.setWindowSpriteMask(this._mask1, this._mask2);
            }
            else
            {
                LayerManager.setWindowSpriteMask(null, null);
            }
            return;
        }// end function

        private function getNextUseMaskRect(param1:int) : Rect3DObject
        {
            var _loc_3:Rect3DObject = null;
            var _loc_2:* = param1 - 1;
            while (_loc_2 >= 0)
            {
                
                _loc_3 = this._rect3dList[_loc_2];
                if (_loc_3.useMask)
                {
                    return _loc_3;
                }
                _loc_2 = _loc_2 - 1;
            }
            return null;
        }// end function

        private function drawGrphic(param1:Graphics, param2:Vector.<IGraphicsData>) : void
        {
            param1.clear();
            param1.beginFill(16711680, 0.4);
            param1.drawGraphicsData(param2);
            param1.endFill();
            return;
        }// end function

        private function getPath(param1:Rectangle) : GraphicsPath
        {
            var _loc_2:* = new Vector.<Number>;
            var _loc_3:* = param1.top;
            var _loc_4:* = param1.left;
            var _loc_5:* = param1.right;
            var _loc_6:* = param1.bottom;
            _loc_2.push(_loc_4, _loc_3, _loc_5, _loc_3, _loc_5, _loc_6, _loc_4, _loc_6, _loc_4, _loc_3);
            var _loc_7:* = new GraphicsPath(this.drawingCommand, _loc_2);
            return _loc_7;
        }// end function

        private function spliteRect(param1:Rectangle, param2:Array, param3:Vector.<IGraphicsData>) : void
        {
            var _loc_7:Rectangle = null;
            var _loc_8:Rectangle = null;
            var _loc_9:Number = NaN;
            var _loc_10:int = 0;
            var _loc_11:int = 0;
            var _loc_12:int = 0;
            var _loc_13:Number = NaN;
            var _loc_14:int = 0;
            var _loc_15:int = 0;
            var _loc_16:int = 0;
            var _loc_4:* = param2.length;
            var _loc_5:Rectangle = null;
            var _loc_6:int = 0;
            while (_loc_6 < _loc_4)
            {
                
                _loc_7 = param2[_loc_6];
                _loc_8 = _loc_7.intersection(param1);
                if (_loc_8.width * _loc_8.height > 0)
                {
                    _loc_9 = _loc_7.x;
                    _loc_10 = _loc_7.y;
                    _loc_11 = _loc_8.x;
                    _loc_12 = _loc_8.y;
                    _loc_13 = _loc_7.right;
                    _loc_14 = _loc_7.bottom;
                    _loc_15 = _loc_8.right;
                    _loc_16 = _loc_8.bottom;
                    _loc_5 = null;
                    if (_loc_12 > _loc_10)
                    {
                        _loc_5 = new Rectangle(_loc_9, _loc_10, _loc_7.width, _loc_12 - _loc_10);
                        param2[_loc_6] = _loc_5;
                        param3[_loc_6] = this.getPath(_loc_5);
                    }
                    if (_loc_11 > _loc_9)
                    {
                        if (!_loc_5)
                        {
                            _loc_5 = new Rectangle(_loc_9, _loc_12, _loc_11 - _loc_9, _loc_8.height);
                            param2[_loc_6] = _loc_5;
                            param3[_loc_6] = this.getPath(_loc_5);
                        }
                        else
                        {
                            _loc_5 = new Rectangle(_loc_9, _loc_12, _loc_11 - _loc_9, _loc_8.height);
                            param2.push(_loc_5);
                            param3.push(this.getPath(_loc_5));
                        }
                    }
                    if (_loc_15 < _loc_13)
                    {
                        if (!_loc_5)
                        {
                            _loc_5 = new Rectangle(_loc_15, _loc_12, _loc_13 - _loc_15, _loc_8.height);
                            param2[_loc_6] = _loc_5;
                            param3[_loc_6] = this.getPath(_loc_5);
                        }
                        else
                        {
                            _loc_5 = new Rectangle(_loc_15, _loc_12, _loc_13 - _loc_15, _loc_8.height);
                            param2.push(_loc_5);
                            param3.push(this.getPath(_loc_5));
                        }
                    }
                    if (_loc_16 < _loc_14)
                    {
                        if (!_loc_5)
                        {
                            _loc_5 = new Rectangle(_loc_9, _loc_16, _loc_7.width, _loc_14 - _loc_16);
                            param2[_loc_6] = _loc_5;
                            param3[_loc_6] = this.getPath(_loc_5);
                        }
                        else
                        {
                            _loc_5 = new Rectangle(_loc_9, _loc_16, _loc_7.width, _loc_14 - _loc_16);
                            param2.push(_loc_5);
                            param3.push(this.getPath(_loc_5));
                        }
                    }
                    if (!_loc_5)
                    {
                        param2.splice(_loc_6, 1);
                        param3.splice(_loc_6, 1);
                        _loc_6 = _loc_6 - 1;
                        _loc_4 = _loc_4 - 1;
                    }
                }
                _loc_6++;
            }
            return;
        }// end function

        public function isRectContains(param1:Number, param2:Number) : Boolean
        {
            var _loc_5:Rect3DObject = null;
            var _loc_3:* = this._rect3dList.length;
            var _loc_4:* = _loc_3 - 1;
            while (_loc_4 >= 0)
            {
                
                _loc_5 = this._rect3dList[_loc_4];
                if (!_loc_5.hasClose && !_loc_5.isHide)
                {
                    if (_loc_5.rect.contains(param1, param2))
                    {
                        return true;
                    }
                }
                _loc_4 = _loc_4 - 1;
            }
            return false;
        }// end function

    }
}
